package model

import (
    "encoding/json"
    "errors"
    "git.inspur.com/x/models"
)

type FuncAlias struct {
    AliasId     string      `json:"aliasId" valid:"-" xorm:"'id' pk"`
    FuncId      string      `json:"funcId" valid:"-"`
    FuncName    string      `json:"funcName" valid:"-"`
    GroupId     string      `json:"groupId" valid:"-"`
    AliasName   string      `json:"aliasName" valid:"length(2|20)~valid.alias.name_length,matches(^(([a-z0-9][a-z0-9-]*)?[a-z0-9])?$)~valid.alias.name_match" xorm:"'name'"`
    Description string      `json:"description" valid:"length(0|2000)~valid.alias.desc,optional"`
    TrafficRule Rule        `json:"rule" xorm:"json" valid:"-"`
    DeleteTime  models.Time `xorm:"deleted" valid:"-"`
    CreateTime  models.Time `xorm:"created" valid:"-"`
    UpdateTime  models.Time `xorm:"updated" valid:"-"`
    Creator     string      `json:"-" valid:"-" xorm:"-"`
    GroupName   string      `json:"-" valid:"-" xorm:"-"`
    AccountId   string      `json:"-" valid:"-" xorm:"-"`
}

func (f FuncAlias) TableName() string {
    return "fcs_func_alias"
}

func CreateAlias(alias *FuncAlias) (*FuncAlias, error) {

    if _, err := models.Engine.Insert(alias); err != nil {
        _ = logger.Error("CreateAlias: insert error %v", err)
        return nil, err
    }
    return alias, nil
}

func UpdateAlias(alias *FuncAlias) (*FuncAlias, error) {
    line, err := models.Engine.ID(alias.AliasId).Update(alias)
    if err != nil {
        _ = logger.Error("UpdateAlias: update alias error %v", err)
        return nil, err
    }
    if line == 0 {
        funcInfoJson, _ := json.Marshal(alias)
        _ = logger.Warn("UpdateAlias: did not update func_alias, alias=%s", string(funcInfoJson))
        return nil, errors.New("UpdateAlias func_alias failed")
    }
    return alias, nil
}

func GetAlias(funcId, aliasName string) (*FuncAlias, error) {
    alias := new(FuncAlias)
    has, err := models.Engine.Where("func_id=?", funcId).And("name=?", aliasName).Get(alias)
    if err != nil {
        _ = logger.Error("GetAlias: get func_alias error %v", err)
        return nil, err
    }
    if !has {
        _ = logger.Warn("GetAlias: did not find func_alias, funcId=%s, aliasName=%s", funcId, aliasName)
        return nil, errors.New("get func_alias failed")
    }
    return alias, nil
}

func GetAliasList(funcId string) ([]*FuncAlias, error) {
    aliasList := make([]*FuncAlias, 0)
    err := models.Engine.Where("func_id=?", funcId).Desc("create_time").Find(&aliasList)
    if err != nil {
        _ = logger.Error("GetAliasList: get alias list error %v", err)
        return nil, err
    }
    return aliasList, nil
}

func DeleteAlias(funcId, aliasName string) error {
    line, err := models.Engine.Where("func_id=?", funcId).And("name=?", aliasName).Delete(&FuncAlias{})
    if err != nil {
        _ = logger.Error("DeleteAlias: delete alias error %v", err)
        return err
    }
    if line == 0 {
        _ = logger.Warn("DeleteAlias: did not delete alias, funcId=%s, aliasName=%s", funcId, aliasName)
        return errors.New("delete func_alias failed")
    }
    return nil
}

func DeleteFunctionAliasByFunc(funcId string) (int64, error) {
    line, err := models.Engine.Where("func_id=?", funcId).Delete(new(FuncAlias))
    if err != nil {
        _ = logger.Error("DeleteFunctionAliasByFunc: delete funcAlias error %v", err)
        return 0, err
    }
    // 函数可能没有别名，所以这里没有删除的数据的话是正常的
    if line == 0 {
        logger.Info("DeleteFunctionAliasByFunc: did not delete func_alias, funcId=%v", funcId)
        return 0, nil
    }
    return line, err
}

func GetAliasCount(funcId string) (int64, error) {
    count, err := models.Engine.Where("func_id=?", funcId).Count(new(FuncAlias))
    if err != nil {
        _ = logger.Error("GetAliasCount: get alias count error %v", err)
        return 0, err
    }
    return count, err
}

func CheckAliasExist(funcId, aliasName string) (bool, error) {
    f := &FuncAlias{}
    return models.Engine.Table("fcs_func_alias").Where("func_id=?", funcId).And("name=?", aliasName).Exist(f)
}
